﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace WinFormLogger.Communication
{
    public abstract class CommunicationBase:IDisposable
    {
        /// <summary>
        /// 取消令牌
        /// </summary>
        public CancellationTokenSource cancellationTokenSource;

        protected ProtocolParse protocolParse {get;set;}
        /// <summary>
        /// 连接状态
        /// </summary>
        public bool IsConnected { get; protected set; }

        /// <summary>
        /// 连接状态改变事件
        /// </summary>
        public event EventHandler<bool> ConnectStatusChanged;

        /// <summary>
        /// 数据发送
        /// </summary>
        public event EventHandler<MesseageEventArgs> MessageSend;

        /// <summary>
        /// 数据接收
        /// </summary>
        public event EventHandler<MesseageEventArgs> MessageReceive;

        /// <summary>
        /// 错误事件
        /// </summary>
        public event EventHandler<Exception> ErrorOccured;

        /// <summary>
        /// 触发数据接收
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnMessageReceive(MesseageEventArgs e)
        {
            MessageReceive?.Invoke(this, e);
        }

        /// <summary>
        /// 触发连接改变事件状态
        /// </summary>
        /// <param name="isConnnected">是否已经连接</param>
        protected virtual void OnConnectStatusChanged(bool isConnnected)
        {
            IsConnected = isConnnected;
            ConnectStatusChanged?.Invoke(this,isConnnected);//this表示当前对象实例，isConnected是传递给事件处理程序的参数。
        }

        /// <summary>
        /// 触发错误事件
        /// </summary>
        /// <param name="exception"></param>
        protected virtual void OnErrorOccured(Exception exception)
        {
            ErrorOccured?.Invoke(this, exception);
        }

        /// <summary>
        /// 线程安全的发送队列
        /// </summary>
        public ConcurrentQueue<byte[]> SendQueue { get; } = new ConcurrentQueue<byte[]>();

        /// <summary>
        /// 触发消息发送
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnMessageSend(MesseageEventArgs e)
        {
            MessageSend?.Invoke(this,e);
        }

       
        public CommunicationBase(ProtocolParse _protocolParse = null)
        {
            protocolParse = _protocolParse;
        }

        /// <summary>
        /// 连接方法
        /// </summary>
        /// <returns></returns>
        public abstract Task<bool> ConnnectAsync();

        /// <summary>
        /// 断开方法
        /// </summary>
        /// <returns></returns>
        public abstract Task DisconnectAsync();

        /// <summary>
        /// 发送方法发送协议数据
        /// </summary>
        /// <returns></returns>
        public abstract Task<bool> SendAsync(byte[] data);

        /// <summary>
        /// 发送方法
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public virtual async Task<bool> SendAsync(string message) 
        {
            byte[] data = System.Text.Encoding.UTF8.GetBytes(message);   
            return await SendAsync(data);
        }
        /// <summary>
        /// 启动发送线程
        /// </summary>
        protected virtual void StartSendingTask() 
        {
            cancellationTokenSource = new CancellationTokenSource();
            Task.Run(ProcessSendQueueAsync, cancellationTokenSource.Token);
        }

        /// <summary>
        /// 处理发送队列中的数据
        /// </summary>
        /// <returns></returns>
        protected abstract Task ProcessSendQueueAsync();

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 设置超时时间
        /// </summary>
        public int ConnectTimeout { get; set; }
        
    }
}
